package com.mc.fastkit.widget.queue

import android.content.Context
import android.os.Handler
import android.os.Looper
import androidx.annotation.UiContext
import com.mc.fastkit.ext.activity
import com.mc.fastkit.ext.isMainThread
import java.util.LinkedList

/**
 * 排队处理
 * @author: MasterChan
 * @date: 2025-04-09 17:31
 */
class WorkQueue private constructor() {

    companion object {
        val instance by lazy { WorkQueue() }
        fun newInstance() = WorkQueue()
    }

    private val queue = LinkedList<WorkAction>()
    private var isWorking = false
    private val handler by lazy { Handler(Looper.getMainLooper()) }

    private fun startWork() {
        isWorking = true
    }

    private fun finishWork() {
        isWorking = false
    }

    private fun nextWork() {
        if (!isWorking && queue.isNotEmpty()) {
            queue.poll()?.let { process(it) }
        }
    }

    private fun nextWorkSafe() {
        if (!isMainThread) {
            handler.post { nextWork() }
        } else {
            nextWork()
        }
    }

    private fun finishAndNextWork() {
        finishWork()
        nextWorkSafe()
    }

    private fun process(workAction: WorkAction) {
        startWork()
        try {
            if (workAction.contextRef != null) {
                val activity = workAction.contextRef!!.get()?.activity
                if (activity == null || activity.isDestroyed || activity.isFinishing) {
                    finishAndNextWork()
                } else {
                    workAction.work.invoke { finishAndNextWork() }
                }
            } else {
                workAction.work.invoke { finishAndNextWork() }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            finishAndNextWork()
        }
    }

    fun post(work: (OnWorkCompleteListener) -> Unit): Int {
        val workAction = WorkAction(null, work)
        queue.offer(workAction)
        nextWorkSafe()
        return workAction.id
    }

    fun postUI(@UiContext context: Context, work: (OnWorkCompleteListener) -> Unit): Int {
        val workAction = WorkAction(context, work)
        queue.offer(workAction)
        nextWorkSafe()
        return workAction.id
    }

    fun post(workAction: WorkAction): Int {
        queue.offer(workAction)
        nextWorkSafe()
        return workAction.id
    }

    fun postFirst(work: (OnWorkCompleteListener) -> Unit): Int {
        val workAction = WorkAction(null, work)
        queue.offerFirst(workAction)
        nextWorkSafe()
        return workAction.id
    }

    fun postUIFirst(@UiContext context: Context, work: (OnWorkCompleteListener) -> Unit): Int {
        val workAction = WorkAction(context, work)
        queue.offerFirst(workAction)
        nextWorkSafe()
        return workAction.id
    }

    fun postFirst(workAction: WorkAction): Int {
        queue.offerFirst(workAction)
        nextWorkSafe()
        return workAction.id
    }

    fun remove(workAction: WorkAction) {
        queue.remove(workAction)
    }

    fun remove(id: Int) {
        queue.removeAll { it.id == id }
    }

    fun clear() {
        isWorking = false
        queue.clear()
    }
}